package hos.ksl

import android.app.Dialog
import android.content.Context
import android.content.ContextWrapper
import android.graphics.drawable.GradientDrawable
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import com.google.android.material.bottomsheet.BottomSheetDialog
import hos.dialog.AlertDialogFragment
import hos.dialog.CustomBottomSheetDialogFragment
import hos.dialog.CustomDialogFragment

/**
 * <p>Title: Dialog </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @date : 2024-05-09 17:22
 * @version : 1.0
 */


inline fun View.createDialog(body: AlertDialog.Builder.() -> Unit) = context.createDialog(body)
inline fun Dialog.createDialog(body: AlertDialog.Builder.() -> Unit) = context.createDialog(body)
inline fun Fragment.createDialog(body: AlertDialog.Builder.() -> Unit) = context?.createDialog(body)

inline fun Context.createDialog(body: AlertDialog.Builder.() -> Unit): AlertDialog.Builder {
    val dialog = AlertDialog.Builder(this)
    dialog.body()
    return dialog
}

@JvmOverloads
inline fun Context.createDialogLayout(
    rootId: Int,
    drawable: (GradientDrawable.() -> Unit) = {},
    job: View.(dialog: AlertDialog.Builder) -> Unit
): AlertDialog.Builder {
    return View.inflate(this, rootId, null)
        .createDialogLayout(drawable, job)
}

@JvmOverloads
inline fun View.createDialogLayout(
    drawable: GradientDrawable.() -> Unit = {},
    job: View.(dialog: AlertDialog.Builder) -> Unit
): AlertDialog.Builder {
    gradient(drawable = drawable)
    val builder = AlertDialog.Builder(context).setView(this)
    job.invoke(
        this, builder
    )
    return builder
}

@JvmOverloads
fun Window.setDialogGravity(gravity: Int = Gravity.CENTER) {
    setBackgroundDrawableResource(android.R.color.transparent)
    val group = decorView as ViewGroup
    val child = group.getChildAt(0) as ViewGroup
    child.post {
        val param = attributes ?: WindowManager.LayoutParams()
        if (gravity == Gravity.BOTTOM) {
            param.width = WindowManager.LayoutParams.MATCH_PARENT
        } else {
            param.width = (width() * 0.8).toInt()
        }
        param.gravity = gravity
        setGravity(gravity)
        attributes = param
    }
}

@JvmOverloads
fun AlertDialog.Builder.showDialog(gravity: Int = Gravity.CENTER) {
    show().window?.setDialogGravity(gravity)
}

@JvmOverloads
fun AlertDialog.Builder.showDialogFragment(
    manager: FragmentManager? = null,
    tag: String = javaClass.simpleName
): AlertDialogFragment {
    val dialogFragment = AlertDialogFragment(this)
    dialogFragment.show(manager, tag)
    return dialogFragment
}

@JvmOverloads
fun DialogFragment.show(
    fragmentManager: FragmentManager? = null,
    tag: String = javaClass.simpleName
) {
    if (fragmentManager != null) {
        show(fragmentManager, javaClass.simpleName)
        return
    }
    if (context == null) {
        return
    }
    val contextDialog = (context as ContextWrapper).baseContext
    if (contextDialog !is FragmentActivity) {
        throw RuntimeException("context must FragmentActivity")
    }
    val useManager = contextDialog.supportFragmentManager
    val prev = useManager.findFragmentByTag(tag)
    if (prev != null) {
        useManager.beginTransaction().remove(prev)
    }
    show(useManager, tag)
}

@JvmOverloads
fun createDialogFragment(
    rootId: Int,
    gravity: Int = Gravity.CENTER,
    drawable: GradientDrawable.() -> Unit = {},
    job: View.(fragment: Dialog?) -> Unit
) = CustomDialogFragment(rootId, null, gravity, drawable, job)

@JvmOverloads
fun View.createDialogFragment(
    gravity: Int = Gravity.CENTER,
    drawable: GradientDrawable.() -> Unit = {},
    job: View.(fragment: Dialog?) -> Unit
) = CustomDialogFragment(0, this, gravity, drawable, job)

fun createBottomSheetDialogFragment(
    rootId: Int,
    job: View.(dialog: BottomSheetDialog?) -> Unit
) = CustomBottomSheetDialogFragment(rootId, null, job)

fun View.createBottomSheetDialogFragment(
    job: View.(dialog: BottomSheetDialog?) -> Unit
) = CustomBottomSheetDialogFragment(0, this, job)
